﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Pokemon
{
    enum PokeType
    {
        Normal,
        Fighting,
        Flying,
        Poison,
        Ground,
        Rock,
        Bug,
        Ghost,
        Steel,
        Fire,
        Water,
        Grass,
        Electric,
        Psychic,
        Ice,
        Dragon,
        Dark,
        None,
    }

    enum PokeNature : int
    {
        Bashful,
        Lonely,
        Adamant,
        Naughty,
        Brave,

        Bold,
        Docile,
        Impish,
        Lax,
        Relaxed,

        Modest,
        Mild,
        Hardy,
        Rash,
        Quiet,

        Calm,
        Gentle,
        Careful,
        Quirky,
        Sassy,

        Timid,
        Hasty,
        Jolly,
        Naive,
        Serious,
    }

    public enum PokeAbility
    {
        AirLock,
        ArenaTrap,
        BattleArmor,
        Blaze,
        Cacophony,
        Chlorophyll,
        ClearBody,
        CloudNine,
        ColorChange,
        Compoundeyes,
        CuteCharm,
        Damp,
        Drizzle,
        Drought,
        EarlyBird,
        EffectSpore,
        FlameBody,
        FlashFire,
        Forecast,
        Guts,
        HugePower,
        Hustle,
        HyperCutter,
        Illuminate,
        Immunity,
        InnerFocus,
        Insomnia,
        Intimidate,
        KeenEye,
        Levitate,
        Lightningrod,
        Limber,
        LiquidOoze,
        MagmaArmor,
        MagnetPull,
        MarvelScale,
        Minus,
        NaturalCure,
        Oblivious,
        Overgrow,
        OwnTempo,
        Pickup,
        Plus,
        PoisonPoint,
        Pressure,
        PurePower,
        RainDish,
        RockHead,
        RoughSkin,
        RunAway,
        SandStream,
        SandVeil,
        SereneGrace,
        ShadowTag,
        ShedSkin,
        ShellArmor,
        ShieldDust,
        Soundproof,
        SpeedBoost,
        Static,
        Stench,
        StickyHold,
        Sturdy,
        SuctionCups,
        Swarm,
        SwiftSwim,
        Synchronize,
        ThickFat,
        Torrent,
        Trace,
        Truant,
        VitalSpirit,
        VoltAbsorb,
        WaterAbsorb,
        WaterVeil,
        WhiteSmoke,
        WonderGuard,
    }

    public enum Gender
    {
        None,
        Male,
        Female,
    }

    public enum StatusEffect
    {
        Poison,
        HarshPoison,
        Sleep,
        Paralyze,
        Burn,
        Freeze,
    }

    class Pokemon : Atom
    {
        #region Variables
        public string Name;
        public int Level;
        public int CurrentExp;
        public int ExpToNextLevel;
        public int CurrentHP;

        public int MaxHP;
        public int ATK;
        public int DEF;
        public int SPATK;
        public int SPDEF;
        public int AGI;

        public int BaseHP;
        public int BaseATK;
        public int BaseDEF;
        public int BaseSPATK;
        public int BaseSPDEF;
        public int BaseAGI;

        public byte GenderThreshold;
        public int Personality;
        public int IV;
        public int[] OwnEV;
        public int[] EV;
        public PokeType[] Types = new PokeType[2];
        public PokeNature Nature;
        public PokeAbility[] Ability = new PokeAbility[2];
        public Move[] Moves = new Move[4];
        public List<Effect> Effects = new List<Effect>();
        #endregion

        public Pokemon()
        {
            Personality = Global.Random.Next(int.MinValue, int.MaxValue);
        }

        #region Methods

        public void LevelUp()
        {
            Level += 1;
            int[] IVBonus = IVStatusBonus();

            UpdateStats(IVBonus);
        } //TODO

        private void UpdateStats(int[] IVBonus)
        {
            MaxHP = ((IVBonus[0] + (2 * BaseHP) + OwnEV[0] / 4 + 100) * Level) / 100 + 10;
            ATK = (int)((((IVBonus[1] + (2 * BaseATK) + OwnEV[1] / 4) * Level) / 100 + 5) * ((float)NatureBonus()[0] / 10));
            DEF = (int)((((IVBonus[2] + (2 * BaseDEF) + OwnEV[2] / 4) * Level) / 100 + 5) * ((float)NatureBonus()[1] / 10));
            SPATK = (int)((((IVBonus[3] + (2 * BaseSPATK) + OwnEV[3] / 4) * Level) / 100 + 5) * ((float)NatureBonus()[2] / 10));
            SPDEF = (int)((((IVBonus[4] + (2 * BaseSPDEF) + OwnEV[4] / 4) * Level) / 100 + 5) * ((float)NatureBonus()[3] / 10));
            AGI = (int)((((IVBonus[5] + (2 * BaseAGI) + OwnEV[5] / 4) * Level) / 100 + 5) * ((float)NatureBonus()[4] / 10));
        }

        public int[] NatureBonus()
        {
            int[] bonus = new int[5] { 100, 100, 100, 100, 100 };

            bonus[(int)Nature % 5] -= 10;
            bonus[(int)Nature / 5] += 10;

            return bonus;
        }

        public PokeAbility IVAbility()
        {
            int p = IV >> 31;

            return Ability[p];
        }

        public bool IVEgg()
        {
            int p = (IV << 1) >> 31;

            if (p == 1)
            {
                return true;
            }

            return false;
        }

        public int[] IVStatusBonus()
        {
            int[] bonus = new int[6];

            return bonus;
        }

        public Gender PersGender()
        {
            int p = Personality % 256;

            if (GenderThreshold == 255)
            {
                return Gender.None;
            }

            if (p >= GenderThreshold)
            {
                return Gender.Male;
            }

            return Gender.Female;
        }

        public bool PersShiny()
        {
            int p1 = Personality >> 16;
            int p2 = Personality % (int)Math.Pow(2, 16);

            int E = 0;
            int F = p1 ^ p2;

            if ((E ^ F) < 8)
            {
                return true;
            }

            return false;
        }

        public PokeNature PersNature()
        {
            int p = Personality % 25;

            return (PokeNature)p;
        }

        public static Pokemon operator +(Pokemon first, Pokemon second)
        {
            return null;
        } //TODO

        #endregion
    }
}
